package org.ricks.common.db;

import org.ricks.common.ThreadNameFactory;
import org.ricks.log.Logger;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author chenwei
 * @Description:
 * @date 2020/12/2914:55
 */
public class AsyncRepositoryMgr {


    private static ScheduledExecutorService scheduledExecutor;
    private final List<Runnable> hooks = new LinkedList();

    private static class SingleCase {
        public static final AsyncRepositoryMgr INSTANCE = new AsyncRepositoryMgr();
    }

    private AsyncRepositoryMgr() {

    }

    public static AsyncRepositoryMgr get() {
        return SingleCase.INSTANCE;
    }

    public void shutdown() {
        if (scheduledExecutor != null) {
            Logger.info("async cache repository manager shutdown");
            scheduledExecutor.shutdown();
            try {
                while (!scheduledExecutor.isTerminated()) {
                    scheduledExecutor.awaitTermination(1, TimeUnit.SECONDS);
                }
            } catch (InterruptedException e){
                Logger.error(e.getMessage(), e);
            }
        }
        triggerHook();
    }

    public ScheduledExecutorService getScheduledExecutor() {
        if (scheduledExecutor == null) {
            synchronized (this) {
                if (scheduledExecutor == null) {
                    scheduledExecutor = Executors.newScheduledThreadPool(
                            8,
                            new ThreadNameFactory(1,"AsyncRepositoryMgr"));
                    Logger.info("async cache repository manager create scheduled executor");
                }
            }
        }
        return scheduledExecutor;
    }

    public void addHook(Runnable hook) {
        hooks.add(hook);
    }

    public void triggerHook() {
        hooks.forEach(Runnable::run);
    }
}
